home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr11 / pdox693.zip / TI1113.ASC < prev    next >
Text File  |  1992-09-04  |  12KB  |  463 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.   PRODUCT  :  Paradox                               NUMBER  :  1113
  9.   VERSION  :  4.0
  10.        OS  :  DOS
  11.      DATE  :  September 4, 1992                        PAGE  :  1/7
  12.  
  13.     TITLE  :  LOCATE INDEXORDER
  14.  
  15.  
  16.  
  17.  
  18.   Intended Audience:
  19.   PAL programmers
  20.  
  21.   Prerequisites:
  22.   Thorough understanding of indexes, including key fields, compound
  23.   secondary indexes, maintained indexes, and Image | OrderTable.
  24.   Understand Chapters 3 and 4 of the PAL Programmer's Guide.
  25.   Should have a basic understanding of the LOCATE command.
  26.  
  27.   Purpose:
  28.   This Technical Information sheet expands on and clarifies the
  29.   documentation for LOCATE INDEXORDER.  It provides information on
  30.   the differences between LOCATE and LOCATE INDEXORDER.
  31.  
  32.   Disclaimer:
  33.   The PAL code in this document is skeletal, and should only be
  34.   used as examples.  In particular, an actual application would
  35.   need to do a lot more error checking.
  36.  
  37.  
  38.   A brief review of LOCATE:
  39.  
  40.   LOCATE sets Retval to false if it does not find a record.  You
  41.   can use LOCATE on multiple fields, but they must be the first
  42.   fields in the table structure.  When using LOCATE on multiple
  43.   fields, you do not have to place the cursor in the field you are
  44.   doing the LOCATE on.
  45.  
  46.   LOCATE NEXT does not require a previous LOCATE, unlike ZOOMNEXT,
  47.   so it is ideal for searching from the middle of the table.  It
  48.   always starts searching from the current position.  However, if
  49.   the record you are on contains the value used in LOCATE NEXT, you
  50.   will get a Retval of True without moving anywhere; it is
  51.   necessary to move to the next record for each subsequent LOCATE
  52.   NEXT.
  53.  
  54.   LOCATE searches the table sequentially, so it will only use the
  55.   current field's index if the view is ordered by the current field
  56.   or the key fields(s).  For example, look at the following table:
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.   PRODUCT  :  Paradox                               NUMBER  :  1113
  75.   VERSION  :  4.0
  76.        OS  :  DOS
  77.      DATE  :  September 4, 1992                        PAGE  :  2/7
  78.  
  79.     TITLE  :  LOCATE INDEXORDER
  80.  
  81.  
  82.  
  83.  
  84.   XYZZY ══╦═════ A ══════╦═════ B ══════╦═════ C ══════╗
  85.      1    ║      6       ║      1       ║      7       ║
  86.      2    ║      4       ║      3       ║     12       ║
  87.      3    ║      9       ║      3       ║      1       ║
  88.      4    ║      2       ║      6       ║      5       ║
  89.      5    ║      1       ║      7       ║      9       ║
  90.      6    ║      8       ║      7       ║      1       ║
  91.      7    ║     10       ║      7       ║      7       ║
  92.      8    ║      7       ║     10       ║      8       ║
  93.      9    ║      3       ║     12       ║      4       ║
  94.     10    ║      5       ║     12       ║      5       ║
  95.  
  96.   All fields are type S.  [A] is keyed, and [B] and [C] have
  97.   maintained secondary indexes.  Xyzzy is currently ordered on [B].
  98.   If your cursor is on [B], then LOCATE would use [B]'s index, but
  99.   if the cursor is on [A] or [C] LOCATE would not use [A]'s or
  100.   [C]'s index.  If the table were ordered on [A] (key order), then
  101.   LOCATE would use the current field's index no matter which field
  102.   you were on.
  103.  
  104.  
  105.   LOCATE INDEXORDER
  106.  
  107.   LOCATE INDEXORDER always searches directly through the index,
  108.   regardless of the current OrderTable.  For example, let's use
  109.   Xyzzy again:
  110.  
  111.      VIEW "Xyzzy"
  112.      MOVETO [B]
  113.      ORDERTABLE SELECT "B"
  114.      MOVETO [C]
  115.      LOCATE 1             ; You are on record 3
  116.      LOCATE INDEXORDER 1  ; You are now on record 6 because 8 is
  117.                           ; less than 9 in [A]
  118.  
  119.   It's easier to understand what happened with the LOCATE
  120.   INDEXORDER if you move to field A and do an OrderTable.
  121.  
  122.   Although LOCATE INDEXORDER has many different forms, some of them
  123.   must be used in a specific order within a script: you cannot do a
  124.   LOCATE INDEXORDER NEXT/PREV until you have used one of the forms
  125.   without a NEXT/PREV in it.
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.   PRODUCT  :  Paradox                               NUMBER  :  1113
  141.   VERSION  :  4.0
  142.        OS  :  DOS
  143.      DATE  :  September 4, 1992                        PAGE  :  3/7
  144.  
  145.     TITLE  :  LOCATE INDEXORDER
  146.  
  147.  
  148.  
  149.  
  150.   Basically, LOCATE INDEXORDER NEXT/PREV move the current index
  151.   pointer up and down one position at a time, just the way that UP
  152.   and DOWN move the record pointer one position at a time.  Because
  153.   LOCATE INDEXORDER is based on the index (independent of the
  154.   record pointer), you can change the current record position
  155.   without changing the current index location.  See the example on
  156.   page 4.
  157.  
  158.   LOCATE INDEXORDER has the same restrictions as LOCATE: the cursor
  159.   must either be in the field you want to search on, or use the
  160.   multi-field key search.  The BY keyword allows you to specify a
  161.   compound (multi-field) index, but the cursor must be in the first
  162.   field of the index.
  163.  
  164.   For example, if your cursor is on [B] of Xyzzy, then LOCATE
  165.   INDEXORDER 7 would bring you to record 5.  Now suppose that you
  166.   have a compound index Bc on [B] and [C].  LOCATE INDEXORDER BY
  167.   "Bc" 7 would then take you to record 6 because 1 is less than 7
  168.   or 9 in [C].
  169.  
  170.   Notice that the previous example used only one value even though
  171.   the index Bc is based on two fields.  LOCATE INDEXORDER BY does
  172.   not require that you have the same number of values as there are
  173.   fields in the index, but all of the values that are present must
  174.   match the data types in the indexed fields.
  175.  
  176.  
  177.   LOCATE INDEXORDER BESTMATCH is somewhat similar to LOCATE PATTERN
  178.   or LOCATE INDEXORDER PATTERN, but it is guaranteed to match a
  179.   record.  LOCATE INDEXORDER BESTMATCH searches for records in the
  180.   following sequence:
  181.  
  182.   -- If there is an exact match it will move to the first record
  183.             (in the index) containing that value.
  184.  
  185.   -- If the value is larger than the maximum value in the field, it
  186.             will move to the record containing the last occurrence
  187.             of the maximum value in the field.
  188.  
  189.   -- Otherwise, it will move to the first record containing a
  190.             higher value than the one searched for.
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.   PRODUCT  :  Paradox                               NUMBER  :  1113
  207.   VERSION  :  4.0
  208.        OS  :  DOS
  209.      DATE  :  September 4, 1992                        PAGE  :  4/7
  210.  
  211.     TITLE  :  LOCATE INDEXORDER
  212.  
  213.  
  214.  
  215.  
  216.   LOCATE INDEXORDER FIRST/LAST should be considered equivalent to
  217.   LOCATE INDEXORDER MIN/MAX.  It moves the index pointer to the
  218.   first or last entry in the index, then moves the record pointer
  219.   to the appropriate record.  For example (using Xyzzy again), if
  220.   you move to [C] and do a LOCATE INDEXORDER FIRST, you will go to
  221.   record 6; LOCATE INDEXORDER LAST will place the cursor on
  222.   record 2.
  223.  
  224.  
  225.   EXAMPLES
  226.  
  227.   The following table represents travel expenses for salesmen.
  228.   When they come back to the office, they turn in their records;
  229.   each transaction receives a unique Id number.  Because the
  230.   salesmen return their receipts in a jumbled pile, the dates end
  231.   up a bit scrambled, so most people view it with an OrderTable on
  232.   [Date].
  233.  
  234.   Transact:
  235.      Id       N*
  236.      Date     D
  237.      Account  A5
  238.      Amount   $
  239.  
  240.   [Date] and [Account] both have maintained secondary indexes.
  241.  
  242.   TRANSACT ═╦═══ Id ═══╦═══ Date ═══╦═ Account ═╦═══ Amount ═══╗
  243.        1    ║   25126  ║   5/29/92  ║    TRAV   ║     579.00   ║
  244.        2    ║   25125  ║   6/01/92  ║    FOOD   ║      35.00   ║
  245.        3    ║   25129  ║   6/03/92  ║    TRAV   ║      88.00   ║
  246.        4    ║   25127  ║   6/04/92  ║    CAR    ║     125.00   ║
  247.        5    ║   25128  ║   6/06/92  ║    FOOD   ║      53.75   ║
  248.        6    ║   25130  ║   6/08/92  ║    TRAV   ║   1,024.00   ║
  249.        7    ║   25131  ║   6/15/92  ║    FOOD   ║      12.00   ║
  250.        8    ║   25132  ║   6/15/92  ║    FOOD   ║      18.30   ║
  251.        9    ║   25134  ║   6/17/92  ║    ENT    ║      75.00   ║
  252.       10    ║   25133  ║   6/18/92  ║    CAR    ║      38.00   ║
  253.  
  254.   The VP of Sales likes to keep a close eye on travel expenses, so
  255.   here's a simple script to help:
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.   PRODUCT  :  Paradox                               NUMBER  :  1113
  273.   VERSION  :  4.0
  274.        OS  :  DOS
  275.      DATE  :  September 4, 1992                        PAGE  :  5/7
  276.  
  277.     TITLE  :  LOCATE INDEXORDER
  278.  
  279.  
  280.  
  281.  
  282.      VIEW "Transact"
  283.      MOVETO FIELD "Date"
  284.      ORDERTABLE SELECT "Date"
  285.      MOVETO [Account]
  286.      LOCATE INDEXORDER "TRAV"         ; This sets up the index
  287.      WHILE TRUE
  288.         WAIT TABLE                    ; Allow user to cursor freely
  289.                                       ; within the table
  290.            PROMPT "Press ESC to quit, Ctrl-PgUp/PgDn to jump" +
  291.                     " between TRAV expenses"
  292.            UNTIL "Esc", "CtrlPgUp", "CtrlPgDn"
  293.         SWITCH
  294.            CASE RETVAL = "Esc" :
  295.               QUITLOOP
  296.            CASE RETVAL = "CtrlPgDn" :
  297.               Fld = FIELD()              ; Save the current field
  298.               MOVETO [Account]
  299.               LOCATE INDEXORDER NEXT "TRAV"
  300.               IF NOT RETVAL THEN BEEP ENDIF
  301.               MOVETO FIELD Fld
  302.            CASE RETVAL = "CtrlPgUp" :
  303.               Fld = FIELD()
  304.               MOVETO [Account]
  305.               LOCATE INDEXORDER PREV "TRAV"
  306.               IF NOT RETVAL THEN BEEP ENDIF
  307.               MOVETO FIELD Fld
  308.         ENDSWITCH
  309.      ENDWHILE
  310.      CLEARIMAGE
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.   PRODUCT  :  Paradox                               NUMBER  :  1113
  339.   VERSION  :  4.0
  340.        OS  :  DOS
  341.      DATE  :  September 4, 1992                        PAGE  :  6/7
  342.  
  343.     TITLE  :  LOCATE INDEXORDER
  344.  
  345.  
  346.  
  347.  
  348.   Another commonly-requested feature is the ability to jump to the
  349.   last record or the second-to-last record.  Suppose that you want
  350.   to see the next-to-last FOOD entry:
  351.  
  352.      VIEW "Transact"
  353.      MOVETO [Account]
  354.      LOCATE INDEXORDER "FOOD"
  355.      WHILE RETVAL               ; Keep looping through until you
  356.                                 ; get to the last FOOD item.
  357.         LOCATE INDEXORDER NEXT "FOOD"
  358.      ENDWHILE
  359.      LOCATE INDEXORDER PREV "FOOD"
  360.  
  361.  
  362.  
  363.  
  364.   A trick for jumping to the last record containing a specific
  365.   value that works well with S or D type fields is the following:
  366.  
  367.      ACCEPT "D" TO Date
  368.      VIEW "Transact"
  369.      MOVETO [Date]
  370.      LOCATE INDEXORDER Date     ; Make sure that Date exists
  371.      IF RETVAL THEN
  372.            ; The next line finds the closest match after the Date
  373.            ; you are looking for.  Note the assumption that Date is
  374.            ; not the maximum date in this field.
  375.         LOCATE INDEXORDER BESTMATCH Date+1
  376.            ; Now move back one record.  You could use UP, but that
  377.            ; wouldn't maintain the index pointer.
  378.         LOCATE INDEXORDER PREV Date
  379.      ELSE
  380.         BEEP
  381.         CLEARIMAGE
  382.         QUIT "Sorry, no match was found"
  383.      ENDIF
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.   PRODUCT  :  Paradox                               NUMBER  :  1113
  405.   VERSION  :  4.0
  406.        OS  :  DOS
  407.      DATE  :  September 4, 1992                        PAGE  :  7/7
  408.  
  409.     TITLE  :  LOCATE INDEXORDER
  410.  
  411.  
  412.  
  413.  
  414.   A similar technique works for A fields where the value searched
  415.   for is less than the length of the field:
  416.  
  417.      ACCEPT "A4" TO Account
  418.      VIEW "Transact"
  419.      MOVETO [Account]           ; This is an A5
  420.      LOCATE INDEXORDER Account
  421.      IF RETVAL THEN
  422.            ; Use the next higher alpha string
  423.         LOCATE INDEXORDER BESTMATCH Account + CHR(1)
  424.         LOCATE INDEXORDER PREV Account
  425.      ELSE
  426.         BEEP
  427.         CLEARIMAGE
  428.         QUIT "Sorry, no match was found"
  429.      ENDIF
  430.  
  431.  
  432.  
  433.   If the search string were the same length as the field, you would
  434.   need to use (with the ASCII sort order):
  435.  
  436.      LOCATE INDEXORDER BESTMATCH SUBSTR(Account, 1,
  437.         LEN(Account) - 1 ) +
  438.         CHR ( ASC ( SUBSTR(Account, LEN(Account), 1) ) + 1 )
  439.  
  440.   DISCLAIMER: You have the right to use this technical information
  441.   subject to the terms of the No-Nonsense License Statement that
  442.   you received with the Borland product to which this information
  443.   pertains.
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.